「身份驗證守門人」一章最後提到,如果上游服務節點有其他路徑可以鑽,那麼一切保護如同虛設。其實目前就有一個流行環境,天然的就隔離了內外流量----是的,就是Kubernetes(K8S)。在K8S環境外部要存取K8S內服務,通常需要透過port-forward
、proxy
或Service
物件的方式。這一章分享透過Apache APISIX作爲K8S Service,配合身份驗證存取K8S Dashboard的方式。
這種在邊界的API網關,有時又被稱作「Edge Gateway」。
不過,通常來說,存取K8S環境更實務做法會透過Ingress和Ingress Controller的方式處理。但依我理解上也不完全不需要Service。
K8S環境建立並不是本系列重點,此處直接使用minikube
快速建立環境。以此章Lab提供給minikube
的backend使用docker
,建立兩個節點的K8S環境:
minikube start --nodes 2
以我建立的兩個服務節點IP是192.168.49.2
、192.168.49.3
,之後會透過這兩個IP存取K8S環境內服務。
minikube 192.168.49.2
minikube-m02 192.168.49.3
然後也直接透過minikube
建立dashboard
服務:
minikube dashboard enable dashboard
可以進一步啓用
metrics-server
minikube addons enable metrics-server
可以透過minikube service list
或kubectl get service -A -o wide
建立的Service。
使用minikube dashboard --url
或kubectl port-forward
取得連接瀏覽Dashboard。
老實說我有點意外用minikube addon建立的dashboard服務不需要輸入token...
透過docker compose建立keycloak服務:
services:
keycloak:
image: "quay.io/keycloak/keycloak:22.0.5"
restart: unless-stopped
network_mode: host
environment:
TZ: "Asia/Taipei"
KC_HTTP_ENABLED: "true"
# KC_HTTPS_PORT: 8444
KEYCLOAK_ADMIN: admin
KEYCLOAK_ADMIN_PASSWORD: admin
KC_HOSTNAME_STRICT: "false"
KC_HTTP_RELATIVE_PATH: "/auth"
command: ['start-dev', '--transaction-xa-enabled', 'false']
雖然多少變化有點多了,不過Keycloak可以參考「用Keycloak學習身份驗證與授權」。建立User bob
、Client ID k8s-lab
。Client ID需要啓用Client authentication
以取得Client Secret,並且加上允許的Redirect URI: http://192.168.49.2:30080/*
和http://192.168.49.3:30080/*
。這會是K8S服務使用的位置,也就是minikube建立的兩個節點IP。
接下來的K8S資源會建立在apisix
的命名空間,先建立該命名空間:
kubectl create ns apisix
透過ConfigMap建立apisix_config/config.yaml
檔案:
apiVersion: v1
kind: ConfigMap
metadata:
name: apisix-conf
namespace: apisix
data:
config.yaml: |-
deployment:
role: data_plane
role_data_plane:
config_provider: yaml
apisix:
node_listen: 9080 # APISIX listening port
enable_heartbeat: true
不同的是這次Lab使用靜態檔案方式獨立部署。所以需要另外準備一份apisix.yaml
:
注意:檔案必須是
#END
結尾
apiVersion: v1
kind: ConfigMap
metadata:
name: apisix-route
namespace: apisix
data:
apisix.yaml: |-
routes: #for example
-
uris:
- /
- /*
upstream:
nodes:
"kubernetes-dashboard.kubernetes-dashboard.svc.cluster.local:80": 1
scheme: http
type: roudrobin
plugins:
openid-connect:
client_id: k8s-lab
client_secret: <填入Keycloak提供的Client Secret>
discovery: https://127.0.0.1:8080/auth/realms/master/.well-known/openid-configuration
realm: master
bearer_only: false
redirect_uri: /middle/callback
logout_path: /middle/logout
access_token_in_authorization_header: true
ssl_verify: false
unauth_action: pass
#END
只設定了一組路由,其反向代理K8S在kubernetes-dashboard
命名空間的kubernetes-dashboard
服阿。特別留意openid-connect
Plugin部分,填入Keycloak服務資訊。注意redirect_uri
不能是真實存在的端點,這個位置會被APISIX使用。
然後準備Deployment或Daemon,並將這兩份ConfigMap掛上:
apiVersion: apps/v1
kind: Deployment
metadata:
name: apisix
namespace: apisix
labels:
app.kubernetes.io/name: apisix
spec:
replicas: 2
selector:
matchLabels:
app.kubernetes.io/name: apisix
template:
metadata:
labels:
app.kubernetes.io/name: apisix
spec:
containers:
- name: apisix
image: "apache/apisix:3.2.2-debian"
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 9080
protocol: TCP
- name: tls
containerPort: 9443
protocol: TCP
- name: admin
containerPort: 9180
protocol: TCP
readinessProbe:
failureThreshold: 6
initialDelaySeconds: 10
periodSeconds: 10
successThreshold: 1
tcpSocket:
port: 9080
timeoutSeconds: 1
lifecycle:
preStop:
exec:
command:
- /bin/sh
- -c
- "sleep 30"
volumeMounts:
- mountPath: /usr/local/apisix/conf/config.yaml
name: apisix-config
subPath: config.yaml
- mountPath: /usr/local/apisix/conf/apisix.yaml
name: apisix-route
subPath: apisix.yaml
resources: {}
volumes:
- configMap:
name: apisix-conf
name: apisix-config
- configMap:
name: apisix-route
name: apisix-route
然後是Servcie:
apiVersion: v1
kind: Service
metadata:
name: apisix
namespace: apisix
spec:
type: NodePort
selector:
app.kubernetes.io/name: apisix
externalTrafficPolicy: Local
ports:
- name: http
port: 9080
nodePort: 30080
- name: https
port: 9443
nodePort: 30443
這裏使用的類型是NodePort
,之後可以透過http://192.168.49.2:30080/*
和http://192.168.49.3:30080/*
存取APISIX服務。在一切完成以後,瀏覽這兩個位置,應該會先跳到Keycloak進行身份驗證。使用bob
帳號登入後就可以進入Dashboard服務。
其實我原本想要在進一步示範設定K8S的
api-server
,使其接受OIDC提供的token與群組,讓不同的Keycloak登入者有不一樣的存取權限。
不過沒想到minikube addon建立的dashboard服務並不需要使用token。就算我把--enable-skip-login
和--disable-settings-authorizer
拿掉也是一樣。雖然後續透過
helm
安裝官方的dashboard倒是可以。但要求OIDC-Provider必須是HTTPS。
恩...還有很多設置需要處理Orz...有時間有機會再分享啦XD!
(之前建立K8S環境是使用kubeadm
建立的。不知道microk8s
的dashboard又是如何?)
雖然我接觸時間不多、接觸也不深。不過也還是略懂一些掌舵技術的。